<template>
  <div class="radio-group-container">
    <div
      class="radio-group-btn-container"
      :style="alignConf"
      @click="onClickSwitchRadio"
    >
      <div
        class="radio-group-btn"
        :style="{ '--width': width, '--height': height, '--padding': padding }"
        :class="{
          'radio-group-btn_active': currentKey == item[fieldNames.value]
        }"
        v-for="item in options"
        :data-key="item[fieldNames.value]"
        :key="item[fieldNames.value]"
      >
        {{ item[fieldNames.label] }}
      </div>
    </div>

    <template v-if="enabledSlot">
      <div class="radio-group-body-container">
        <div
          class="radio-group-body-view-container"
          ref="radioGroupBodyRef"
          :style="{ '--switch-duration': switchDuration }"
        >
          <div
            class="radio-group-body-view-item"
            v-for="item in options"
            :key="item[fieldNames.value]"
          >
            <slot :name="item[fieldNames.value]" :item="item"></slot>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
export default {
  name: "RadioGroup",
  props: {
    options: {
      type: Array,
      default: () => []
    },
    activeKey: {
      type: [String, Number],
      default: undefined
    },
    fieldNames: {
      type: Object,
      default: () => ({
        label: "label",
        value: "key"
      })
    },
    switchDuration: {
      type: String,
      default: "0.4s"
    },
    enabledSlot: {
      type: Boolean,
      default: false
    },
    width: {
      type: String,
      default: "auto"
    },
    height: {
      type: String,
      default: "1.5rem"
    },
    padding: {
      type: String,
      default: "0 0.75rem"
    },
    align: {
      type: String,
      default: "left"
    },
    margin: {
      type: String,
      default: "0"
    }
  },
  data() {
    return {
      currentKey: ""
    };
  },

  computed: {
    alignConf() {
      const { align, margin } = this;
      const alignStyleObj = {
        left: {
          marginRight: "auto",
          marginLeft: 0
        },
        right: {
          marginRight: 0,
          marginLeft: "auto"
        },
        center: {
          marginRight: "auto",
          marginLeft: "auto"
        },
        custom: { margin }
      };

      return alignStyleObj[align];
    }
  },

  watch: {
    activeKey: {
      handler(newVal) {
        const { enabledSlot, setRadioGroupContentView, $refs } = this;
        this.currentKey = newVal || this.options[0].key;
        if (enabledSlot && $refs.radioGroupBodyRef) {
          setRadioGroupContentView(this.currentKey);
        }
      },
      immediate: true
    }
  },

  mounted() {
    const { enabledSlot, setRadioGroupContentView, currentKey } = this;
    if (enabledSlot) {
      setRadioGroupContentView(currentKey);
    }
  },

  methods: {
    /**
     * 点击切换 radio 方法
     * @param {Object} e 切换 radio 事件对象
     */
    onClickSwitchRadio(e) {
      const tapKey = e.target.dataset.key;
      if (tapKey == undefined || tapKey == this.currentKey) return;
      this.setRadioGroupContentView(tapKey);
      this.currentKey = tapKey;
      this.$emit("change", this.currentKey);
    },

    /**
     * 设置 radio group 内容视图方法
     * @param {String|Number} key 传入目标 key
     */
    setRadioGroupContentView(key) {
      const { enabledSlot, currentKey, options } = this;
      if (enabledSlot) {
        const preIdx = options.findIndex(item => item.key == currentKey);
        const nextIdx = options.findIndex(item => item.key == key);
        const dir = nextIdx - preIdx;
        const moveX = `translateX(${dir >= 0 ? `${-100 * nextIdx}%` : "0%"})`;
        this.$refs.radioGroupBodyRef.style.transform = moveX;
      }
    }
  }
};
</script>

<style lang="less" scoped>
@width: var(--width);
@height: var(--height);
@padding: var(--padding);

.radio-group-container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  flex-shrink: 0;
  width: 100%;

  .radio-group-btn-container {
    display: flex;
    align-items: center;
    border-radius: 0.125rem;
    background: #1d3350;

    .radio-group-btn {
      z-index: 10;
      display: flex;
      align-items: center;
      justify-content: center;
      width: @width;
      height: @height;
      padding: @padding;
      font-size: 0.75rem;
      font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
      font-weight: 400;
      color: rgba(176, 224, 255, 0.6);
      line-height: 0.875rem;
      user-select: none;
      box-sizing: border-box;
    }

    .radio-group-btn_active {
      background: #1d3350;
      border-radius: 0.125rem;
      border: 1px solid #87cdff;
      color: rgba(255, 255, 255, 0.8);
      text-shadow: 0px 0px 6px rgba(135, 205, 255, 0.8);
    }
  }

  .radio-group-body-container {
    overflow: hidden;
    width: 100%;
    height: 100%;

    .radio-group-body-view-container {
      display: flex;
      align-items: center;
      flex-shrink: 0;
      width: 100%;
      transition: transform var(--switch-duration);

      .radio-group-body-view-item {
        flex-shrink: 0;
        width: 100%;
      }
    }
  }
}
</style>
